home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cug172 / yylex.c < prev   
C/C++ Source or Header  |  1986-02-05  |  6KB  |  186 lines

  1. /*
  2.   HEADER: CUG     nnn.nn;
  3.   TITLE:     LEX - A Lexical Analyser Generator
  4.   VERSION:     1.0 for IBM-PC
  5.   DATE:      Jan 30, 1985
  6.   DESCRIPTION:     A Lexical Analyser Generator. From UNIX
  7.   KEYWORDS:     Lexical Analyser Generator YACC C PREP
  8.   SYSTEM:     IBM-PC and Compatiables
  9.   FILENAME:      YYLEX.C
  10.   WARNINGS:     This program is not for the casual user. It will
  11.          be useful primarily to expert developers.
  12.   CRC:         N/A
  13.   SEE-ALSO:     YACC and PREP
  14.   AUTHORS:     Scott Guthery 11100 leafwood lane Austin, TX 78750
  15.   COMPILERS:     DESMET-C
  16.   REFERENCES:     UNIX Systems Manuals
  17. */
  18. /*
  19.  * Bob Denny 28-Aug-82  Remove reference to stdio.h
  20.  * Remove code to default lexin, change to call to
  21.  * llstin(), generated by lex depending upon setting
  22.  * of "-s" switch.  Eliminates hardwired dependency
  23.  * on standard I/O library.  Moved declaration of
  24.  * lexin to lexgetc().
  25.  *
  26.  * Bob Denny 31-Aug-82  Add call to lexswitch() in
  27.  * the generated file, to switch to the table whose
  28.  * name was given in the "-t" switch (or to "lextab"
  29.  * if "-t" wasn't given).  Removed hardwired setting
  30.  * of _tabp --> "lextab" here. Now handled automagically.
  31.  *
  32.  * Bob Denny 21-Oct-82  Add llinit() function to re-initialize
  33.  * yylex(), making it serially reusable.
  34.  *
  35.  * Initialize _tabp to NULL so lexswitch() to real table happens
  36.  * only once.
  37.  *
  38.  * Bob Denny 15-Apr-83 Move NBPW to LEX.H and make it 32 on VAX native,
  39.  *                     else 16.
  40.  * Scott Guthery 20-Nov-83    Adapt for IBM PC & DeSmet C
  41.  */
  42.  
  43. /*
  44.  * yylex for lex tables
  45.  */
  46.  
  47. #include <lex.h>
  48.  
  49. #define ERROR   256     /* yacc's value */
  50.  
  51. tst__b(c, tab)
  52. register int    c;
  53. char            tab[];
  54. {
  55.         return(tab[(c >> 3) & 037] & (1 << (c & 07)) );
  56. }
  57.  
  58. struct  lextab  *_tabp = 0;
  59.  
  60. extern char     *llsave[];      /* Right-context buffer                 */
  61. char    llbuf[100];             /* work buffer                          */
  62. char    *llp1   = &llbuf[0];    /* pointer to next avail. in token      */
  63. char    *llp2   = &llbuf[0];    /* pointer to end of lookahead          */
  64. char    *llend  = &llbuf[0];    /* pointer to end of token              */
  65. char    *llebuf = &llbuf[sizeof llbuf];
  66. int     lleof;
  67. int     yylval  = 0;
  68. int     yyline  = 0;
  69.  
  70. yylex()
  71. {
  72.         register int c, st;
  73.         int final, l, llk, i;
  74.  
  75.         register struct lextab *lp;
  76.         char *cp;
  77.  
  78.         /*
  79.          * Call llstin() to default lexin to stdin
  80.          * and assign _tabp to "real" table.
  81.          */
  82.         llstin();                       /* Initialize yylex() variables */
  83.  
  84. loop:
  85.         llk = 0;
  86.         if (llset())
  87.                 return(0);              /* Prevent EOF loop     */
  88.         st = 0;
  89.         final = -1;
  90.         lp = _tabp;
  91.  
  92.         do {
  93.                 if (lp->lllook && (l = lp->lllook[st])) {
  94.                         for (c=0; c<NBPW; c++)
  95.                                 if (l&(1<<c))
  96.                                         llsave[c] = llp1;
  97.                         llk++;
  98.                 }
  99.                 if ((i = lp->llfinal[st]) != -1) {
  100.                         final = i;
  101.                         llend = llp1;
  102.                 }
  103.                 if ((c = llinp()) < 0)
  104.                         break;
  105.                 if ((cp = lp->llbrk) && llk==0 && tst__b(c, cp)) {
  106.                         llp1--;
  107.                         break;
  108.                 }
  109.         } while ((st = (*lp->llmove)(lp, c, st)) != -1);
  110.  
  111.  
  112.         if (llp2 < llp1)
  113.                 llp2 = llp1;
  114.         if (final == -1) {
  115.                 llend = llp1;
  116.                 if (st == 0 && c < 0)
  117.                         return(0);
  118.                 if ((cp = lp->llill) && tst__b(c, cp)) {
  119.                         lexerror("Illegal character: %c (%03o)", c, c);
  120.                         goto loop;
  121.                 }
  122.                 return(ERROR);
  123.         }
  124.         if (c = (final >> 11) & 037)
  125.                 llend = llsave[c-1];
  126.         if ((c = (*lp->llactr)(final&03777)) >= 0)
  127.                 return(c);
  128.         goto loop;
  129. }
  130.  
  131. llinp()
  132. {
  133.  
  134.         register c;
  135.         register struct lextab *lp;
  136.         register char *cp;
  137.  
  138.         lp = _tabp;
  139.         cp = lp->llign;                         /* Ignore class         */
  140.         for (;;) {
  141.                 /*
  142.                  * Get the next character from the save buffer (if possible)
  143.                  * If the save buffer's empty, then return EOF or the next
  144.                  * input character.  Ignore the character if it's in the
  145.                  * ignore class.
  146.                  */
  147.                 c = (llp1 < llp2) ? *llp1 & 0377 : (lleof) ? EOF : lexgetc();
  148.                 if (c >= 0) {                   /* Got a character?     */
  149.                         if (cp && tst__b(c, cp))
  150.                                 continue;       /* Ignore it            */
  151.                         if (llp1 >= llebuf) {   /* No, is there room?   */
  152.                                 lexerror("Token buffer overflow");
  153.                                 exit(1);
  154.                         }
  155.                         *llp1++ = c;            /* Store in token buff  */
  156.                 } else
  157.                         lleof = 1;              /* Set EOF signal       */
  158.                 return(c);
  159.         }
  160. }
  161.  
  162. llset()
  163. /*
  164.  * Return TRUE if EOF and nothing was moved in the look-ahead buffer
  165.  */
  166. {
  167.         register char *lp1, *lp2;
  168.  
  169.         for (lp1 = llbuf, lp2 = llend; lp2 < llp2;)
  170.                 *lp1++ = *lp2++;
  171.         llend = llp1 = llbuf;
  172.         llp2 = lp1;
  173.         return(lleof && lp1 == llbuf);
  174. }
  175.  
  176. /*
  177.  * Re-initialize yylex() so that it can be re-used on
  178.  * another file.
  179.  */
  180. llinit()
  181.    {
  182.    llp1 = llp2 = llend = llbuf;
  183.    llebuf = llbuf + sizeof(llbuf);
  184.    lleof = yylval = yyline = 0;
  185.    }
  186.